package com.stary.code.springboot.config;

import java.io.File;
import java.util.Map;
import java.util.Properties;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.stary.code.springboot.Constants;

/**
 * <p>模板配置类</p>
 * @author stary {@link stary1993@qq.com}
 * @since 2018-9-20
 */
public class TemplateConfig {

	private static final Logger logger = LoggerFactory.getLogger(TemplateConfig.class);

	private static final String CONFIG_PATH = File.separator + "config" + File.separator;

	private static final String MAIL_PATH = File.separator + "mail" + File.separator;

	private static final String REDIS_PATH = File.separator + "redis" + File.separator;

	private static final String MONGODB_PATH = File.separator + "mongodb" + File.separator;

	private static final String SHIRO_PATH = File.separator + "shiro" + File.separator;

	private static final String TASK_PATH = File.separator + "task" + File.separator;

	private static final String QUARTZ_PATH = File.separator + "quartz" + File.separator;

	private static final String ACTIVEMQ_PATH = File.separator + "activemq" + File.separator;

	private static final String KAFKA_PATH = File.separator + "kafka" + File.separator;

	private static final String RABBITMQ_PATH = File.separator + "rabbitmq" + File.separator;
	/**
	 * 模板文件Map
	 */
	private Map<String, String> templatesMap;
	/**
	 * 参数Map
	 */
	private Map<String, Object> paramsMap;
	/**
	 * 设置引擎
	 * @return
	 */
	private static VelocityEngine velocity;

	static {
		logger.debug("---------->> 初始化模板引擎 <<----------");
		Properties pro = new Properties(); 
		pro.setProperty(Velocity.OUTPUT_ENCODING, Constants.UTF8); 
		pro.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); 
		pro.setProperty(Constants.VM_LOADPATH_KEY, Constants.VM_LOADPATH_VALUE); 
		velocity = new VelocityEngine(pro);
	}

	/**
	 * 获取参数
	 * @return
	 */
	public VelocityContext getVelocityContext() {
		VelocityContext context = new VelocityContext(paramsMap);
		/*if (paramsMap != null && !paramsMap.isEmpty()) {
			for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
					context.put(entry.getKey(), entry.getValue());
			}
		}*/
		return context;			
	}
	/**
	 * 获取模板路径
	 * @param templateName 模板名称
	 * @return
	 */
	public String getTemplateFilePath(String templateName) {
		if (templateName == null || templateName.contains(Constants.VM_SUFFIX)) {
			return templateName;
		}
		StringBuilder filePath = new StringBuilder(templateName);
		filePath.append(Constants.VM_SUFFIX);
		return filePath.toString();
	}
	/**
	 * 获取模板
	 * @param templateName 模板名称
	 * @return
	 */
	public Template getTemplate(String templateName) {
		templateName = getTemplateFilePath(templateName);
		logger.debug("加载模板文件：{} <<----------", templateName);
		return velocity.getTemplate(templateName, Constants.UTF8);
	}
	/**
	 * 设置默认模板文件
	 * @return
	 */
	public Map<String, String> getTemplatesMap() {
		return templatesMap;
	}

	public TemplateConfig setTemplatesMap(Map<String, String> templatesMap) {
		this.templatesMap = templatesMap;
		return this;
	}

	public Map<String, Object> getParamsMap() {				
		return paramsMap;
	}

	public TemplateConfig setParamsMap(Map<String, Object> paramsMap) {
		this.paramsMap = paramsMap;
		return this;
	}


	/**
	 * 获取输出文件或目录名
	 * @param mavenConfig maven配置
	 * @param templateName 模板名称
	 * @return
	 */
	public String getOutFile(MavenConfig mavenConfig, String templateName) {
		// .xml
		if (templateName.contains(Constants.XML_SUFFIX)) { 
			// pom.xml
			if (templateName.contains(Constants.POM)) {
				return mavenConfig.getArtifactId() + File.separator + Constants.POM + Constants.XML_SUFFIX;
			}
			// logback-spring.xml
			if (templateName.contains(Constants.LOGBACK_SPRING)) {
				return mavenConfig.getMainResourcesDir() + File.separator + Constants.LOGBACK_SPRING + Constants.XML_SUFFIX;
			}
			// ehcache-shiro.xml
			if (templateName.contains(Constants.EHCACHE_SHIRO)) {
				return mavenConfig.getMainResourcesDir() + File.separator + Constants.EHCACHE_SHIRO + Constants.XML_SUFFIX;
			}
			// table_doc.xml 
			if (templateName.contains(Constants.TABLE_DOC)) {
				return mavenConfig.getArtifactId() + File.separator + mavenConfig.getName() + "项目表结构文档" + Constants.DOC_SUFFIX;
			}
		}
		// .properties
		if (templateName.contains(Constants.PROPERTIES_SUFFIX)) {
			// application-dev.properties
			if (templateName.toLowerCase().contains(Constants.APPLICATION_PRO_DEV.toLowerCase())) {
				return mavenConfig.getMainResourcesDir() + File.separator + Constants.APPLICATION_PRO_DEV + Constants.PROPERTIES_SUFFIX;				
			}
			// application-prod.properties
			if (templateName.toLowerCase().contains(Constants.APPLICATION_PRO_PROD.toLowerCase())) {
				return mavenConfig.getMainResourcesDir() + File.separator + Constants.APPLICATION_PRO_PROD + Constants.PROPERTIES_SUFFIX;				
			}
			// application.properties
			if (templateName.toLowerCase().contains(Constants.APPLICATION_PRO.toLowerCase())) {
				return mavenConfig.getMainResourcesDir() + File.separator + Constants.APPLICATION_PRO + Constants.PROPERTIES_SUFFIX;				
			}
			// quartz.properties
			if (templateName.toLowerCase().contains(Constants.QUARTZ.toLowerCase())) {
				return mavenConfig.getMainResourcesDir() + File.separator + Constants.QUARTZ + Constants.PROPERTIES_SUFFIX;				
			}
		}
		// .sql
		if (templateName.contains(Constants.SQL_SUFFIX)) {
			// tables_oracle.sql
			if (templateName.toLowerCase().contains(Constants.QUARTZ_TABLES_ORACLE.toLowerCase())) {
				return mavenConfig.getMainResourcesDir() + QUARTZ_PATH + "dbtable" + File.separator + Constants.QUARTZ_TABLES_ORACLE + Constants.SQL_SUFFIX;				
			}
			// tables_mysql_innodb.sql
			if (templateName.toLowerCase().contains(Constants.QUARTZ_TABLES_MYSQL.toLowerCase())) {
				return mavenConfig.getMainResourcesDir() + QUARTZ_PATH + "dbtable" + File.separator + Constants.QUARTZ_TABLES_MYSQL + Constants.SQL_SUFFIX;				
			}
			// tables_sqlServer.sql
			if (templateName.toLowerCase().contains(Constants.QUARTZ_TABLES_SQL_SERVER.toLowerCase())) {
				return mavenConfig.getMainResourcesDir() + QUARTZ_PATH + "dbtable" + File.separator + Constants.QUARTZ_TABLES_SQL_SERVER + Constants.SQL_SUFFIX;				
			}
		}
		// .java
		if (templateName.contains(Constants.JAVA_SUFFIX)) {
			// SpringBootStartApplication.java
			if (templateName.toLowerCase().contains(Constants.SPRING_BOOT_APPLICATION.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + File.separator + upperCase(mavenConfig.getArtifactId()) + Constants.SPRING_BOOT_APPLICATION + Constants.JAVA_SUFFIX;				
			}
			// ApplicationTests.java
			if (templateName.toLowerCase().contains(Constants.APPLICATION_TESTS.toLowerCase())) {
				return mavenConfig.getTestJavasDir() + File.separator + upperCase(mavenConfig.getArtifactId()) + Constants.APPLICATION_TESTS + Constants.JAVA_SUFFIX;				
			}
			// Application.java
			if (templateName.toLowerCase().contains(Constants.APPLICATION.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + File.separator + upperCase(mavenConfig.getArtifactId()) + Constants.APPLICATION + Constants.JAVA_SUFFIX;				
			}
			// DruidDataSourceConfig.java
			if (templateName.toLowerCase().contains(Constants.DRUID_DATASOURCE_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + CONFIG_PATH + Constants.DRUID_DATASOURCE_CONFIG + Constants.JAVA_SUFFIX;
			}
			// MyBatisPlusConfig.java
			if (templateName.toLowerCase().contains(Constants.MY_BATIS_PLUS_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + CONFIG_PATH + Constants.MY_BATIS_PLUS_CONFIG + Constants.JAVA_SUFFIX;
			}
			// RedisConfig.java
			if (templateName.toLowerCase().contains(Constants.REDIS_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + CONFIG_PATH + Constants.REDIS_CONFIG + Constants.JAVA_SUFFIX;
			}
			// RedisServiceImpl.java
			if (templateName.toLowerCase().contains(Constants.REDIS_SERVICE_IMPL.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + REDIS_PATH + Constants.REDIS_SERVICE_IMPL + Constants.JAVA_SUFFIX;
			}
			// RedisService.java
			if (templateName.toLowerCase().contains(Constants.REDIS_SERVICE.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + REDIS_PATH + Constants.REDIS_SERVICE + Constants.JAVA_SUFFIX;
			}
			// MongoDBServiceImpl.java
			if (templateName.toLowerCase().contains(Constants.MONGODB_SERVICE_IMPL.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + MONGODB_PATH + Constants.MONGODB_SERVICE_IMPL + Constants.JAVA_SUFFIX;
			}
			// MongoDBService.java
			if (templateName.toLowerCase().contains(Constants.MONGODB_SERVICE.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + MONGODB_PATH + Constants.MONGODB_SERVICE + Constants.JAVA_SUFFIX;
			}
			// MongoDB Page.java
			if (templateName.toLowerCase().contains(Constants.MONGODB_PAGE.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + MONGODB_PATH + Constants.MONGODB_PAGE + Constants.JAVA_SUFFIX;
			}
			// MongoDB ReflectionUtils.java
			if (templateName.toLowerCase().contains(Constants.MONGODB_REFLECTIONUTILS.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + MONGODB_PATH + Constants.MONGODB_REFLECTIONUTILS + Constants.JAVA_SUFFIX;
			}
			// MailServiceImpl.java
			if (templateName.toLowerCase().contains(Constants.MAIL_SERVICE_IMPL.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + MAIL_PATH + Constants.MAIL_SERVICE_IMPL + Constants.JAVA_SUFFIX;
			}
			// MailService.java
			if (templateName.toLowerCase().contains(Constants.MAIL_SERVICE.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + MAIL_PATH + Constants.MAIL_SERVICE + Constants.JAVA_SUFFIX;
			}
			// Mail.java
			if (templateName.toLowerCase().contains(Constants.MAIL.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + MAIL_PATH + Constants.MAIL + Constants.JAVA_SUFFIX;
			}
			// ShiroConfig.java
			if (templateName.toLowerCase().contains(Constants.SHIRO_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + CONFIG_PATH + Constants.SHIRO_CONFIG + Constants.JAVA_SUFFIX;
			}
			// ShiroRealm.java
			if (templateName.toLowerCase().contains(Constants.SHIRO_REALM.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + SHIRO_PATH + Constants.SHIRO_REALM + Constants.JAVA_SUFFIX;
			}
			// ShiroTagFreemarkerConfig.java
			if (templateName.toLowerCase().contains(Constants.SHIRO_TAG_FREEMARKER_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + SHIRO_PATH + Constants.SHIRO_TAG_FREEMARKER_CONFIG + Constants.JAVA_SUFFIX;
			}
			// ShiroUtils.java
			if (templateName.toLowerCase().contains(Constants.SHIRO_UTILS.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + SHIRO_PATH + Constants.SHIRO_UTILS + Constants.JAVA_SUFFIX;
			}
			// ScheduleConfig.java
			if (templateName.toLowerCase().contains(Constants.SCHEDULE_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + CONFIG_PATH + Constants.SCHEDULE_CONFIG + Constants.JAVA_SUFFIX;
			}
			// DynamicScheduleTask.java
			if (templateName.toLowerCase().contains(Constants.SCHEDULE_DYNAMIC_TASK.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + TASK_PATH + Constants.SCHEDULE_DYNAMIC_TASK + Constants.JAVA_SUFFIX;
			}
			// QuartzConfig.java
			if (templateName.toLowerCase().contains(Constants.QUARTZ_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + CONFIG_PATH + Constants.QUARTZ_CONFIG + Constants.JAVA_SUFFIX;
			}
			// QuartzServiceImpl.java
			if (templateName.toLowerCase().contains(Constants.QUARTZ_SERVICE_IMPL.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + QUARTZ_PATH + Constants.QUARTZ_SERVICE_IMPL + Constants.JAVA_SUFFIX;
			}
			// QuartzService.java
			if (templateName.toLowerCase().contains(Constants.QUARTZ_SERVICE.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + QUARTZ_PATH + Constants.QUARTZ_SERVICE + Constants.JAVA_SUFFIX;
			}
			// TaskInfo.java
			if (templateName.toLowerCase().contains(Constants.QUARTZ_TASKINFO.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + QUARTZ_PATH + Constants.QUARTZ_TASKINFO + Constants.JAVA_SUFFIX;
			}
			// TaskJob.java
			if (templateName.toLowerCase().contains(Constants.QUARTZ_TASKJOB.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + QUARTZ_PATH + "task" + File.separator + Constants.QUARTZ_TASKJOB + Constants.JAVA_SUFFIX;
			}
			// ActiveMQConfig.java
			if (templateName.toLowerCase().contains(Constants.ACTIVEMQ_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + CONFIG_PATH + Constants.ACTIVEMQ_CONFIG + Constants.JAVA_SUFFIX;
			}
			// ActiveMQProducer.java
			if (templateName.toLowerCase().contains(Constants.ACTIVEMQ_PRODUCER.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + ACTIVEMQ_PATH + Constants.ACTIVEMQ_PRODUCER + Constants.JAVA_SUFFIX;
			}
			// ActiveMQConsumer.java
			if (templateName.toLowerCase().contains(Constants.ACTIVEMQ_CONSUMER.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + ACTIVEMQ_PATH + Constants.ACTIVEMQ_CONSUMER + Constants.JAVA_SUFFIX;
			}
			// KafkaProducer.java
			if (templateName.toLowerCase().contains(Constants.KAFKA_PRODUCER.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + KAFKA_PATH + Constants.KAFKA_PRODUCER + Constants.JAVA_SUFFIX;
			}
			// KafkaConsumer.java
			if (templateName.toLowerCase().contains(Constants.KAFKA_CONSUMER.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + KAFKA_PATH + Constants.KAFKA_CONSUMER + Constants.JAVA_SUFFIX;
			}
			// RabbitMQConfig.java
			if (templateName.toLowerCase().contains(Constants.RABBITMQ_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + CONFIG_PATH + Constants.RABBITMQ_CONFIG + Constants.JAVA_SUFFIX;
			}
			// RabbitMQDirectProducer.java
			if (templateName.toLowerCase().contains(Constants.RABBITMQ_DIRECT_PRODUCER.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + RABBITMQ_PATH + "direct" + File.separator + Constants.RABBITMQ_DIRECT_PRODUCER + Constants.JAVA_SUFFIX;
			}
			// RabbitMQDirectConsumer.java
			if (templateName.toLowerCase().contains(Constants.RABBITMQ_DIRECT_CONSUMER.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + RABBITMQ_PATH + "direct" + File.separator + Constants.RABBITMQ_DIRECT_CONSUMER + Constants.JAVA_SUFFIX;
			}
			// RabbitMQFanoutProducer.java
			if (templateName.toLowerCase().contains(Constants.RABBITMQ_FANOUT_PRODUCER.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + RABBITMQ_PATH + "fanout" + File.separator + Constants.RABBITMQ_FANOUT_PRODUCER + Constants.JAVA_SUFFIX;
			}
			// RabbitMQFanoutConsumer1.java
			if (templateName.toLowerCase().contains(Constants.RABBITMQ_FANOUT_CONSUMER_1.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + RABBITMQ_PATH + "fanout" + File.separator + Constants.RABBITMQ_FANOUT_CONSUMER_1 + Constants.JAVA_SUFFIX;
			}
			// RabbitMQFanoutConsumer2.java
			if (templateName.toLowerCase().contains(Constants.RABBITMQ_FANOUT_CONSUMER_2.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + RABBITMQ_PATH + "fanout" + File.separator + Constants.RABBITMQ_FANOUT_CONSUMER_2 + Constants.JAVA_SUFFIX;
			}
			// RabbitMQTopicProducer.java
			if (templateName.toLowerCase().contains(Constants.RABBITMQ_TOPIC_PRODUCER.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + RABBITMQ_PATH + "topic" + File.separator + Constants.RABBITMQ_TOPIC_PRODUCER + Constants.JAVA_SUFFIX;
			}
			// RabbitMQTopicConsumer.java
			if (templateName.toLowerCase().contains(Constants.RABBITMQ_TOPIC_CONSUMER.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + RABBITMQ_PATH + "topic" + File.separator + Constants.RABBITMQ_TOPIC_CONSUMER + Constants.JAVA_SUFFIX;
			}
			// RabbitMQTopicConsumers.java
			if (templateName.toLowerCase().contains(Constants.RABBITMQ_TOPIC_CONSUMERS.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + RABBITMQ_PATH + "topic" + File.separator + Constants.RABBITMQ_TOPIC_CONSUMERS + Constants.JAVA_SUFFIX;
			}
			// BeetlTemplateConfig.java
			if (templateName.toLowerCase().contains(Constants.BEETL_TEMPLATE_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + CONFIG_PATH + Constants.BEETL_TEMPLATE_CONFIG + Constants.JAVA_SUFFIX;
			}
			// BeetlsqlConfig.java
			if (templateName.toLowerCase().contains(Constants.BEETLSQL_CONFIG.toLowerCase())) {
				return mavenConfig.getMainJavaDir() + CONFIG_PATH + Constants.BEETLSQL_CONFIG + Constants.JAVA_SUFFIX;
			}
		}
		// 目录
		if (!templateName.contains(Constants.POINT)) {
			// /templates
			if (templateName.contains(Constants.TEMPLATES)) {
				return mavenConfig.getMainResourcesDir() + File.separator + Constants.TEMPLATES;
			}
			// /static
			if (templateName.contains(Constants.STATIC)) {
				return mavenConfig.getMainResourcesDir() + File.separator + Constants.STATIC;
			}
			// test
			if (templateName.contains(Constants.TEST)) {
				return mavenConfig.getTestJavasDir();
			}
			// /WEB-INF/jsp
			if (templateName.contains(Constants.TEMPLATE_JSP)) {
				return mavenConfig.getWebappDir() + File.separator + Constants.TEMPLATE_JSP + File.separator + Constants.JSP;
			}			
		}
		return null;
	}

	/**
	 * 处理字符串 带有特殊字符 "-","_"," " 截取首字母大写拼接
	 * @param str
	 * @return
	 */
	public String upperCase(String str) {
		if (str.contains(Constants.UNDERLINE) || str.contains(Constants.LINE) || str.contains(Constants.SPACE)) {
			if (str.contains(Constants.UNDERLINE)) {
				StringBuilder builder = new StringBuilder();
				String[] array=str.split(Constants.UNDERLINE);
				for (int i = 0; i < array.length; i++) {
					String newStr = array[i].substring(0, 1).toUpperCase() + array[i].substring(1);
					builder.append(newStr);
				}
				str = builder.toString();  
			}
			if (str.contains(Constants.LINE)) {
				StringBuilder builder = new StringBuilder();
				String[] array = str.split(Constants.LINE);
				for (int i = 0; i < array.length; i++) {
					String newStr = array[i].substring(0, 1).toUpperCase() + array[i].substring(1);
					builder.append(newStr);
				}
				str = builder.toString();
			}
			if (str.contains(Constants.SPACE)) {
				StringBuilder builder = new StringBuilder();
				String[] array = str.split(Constants.SPACE);
				for (int i = 0; i < array.length; i++) {
					String newStr = array[i].substring(0, 1).toUpperCase() + array[i].substring(1);
					builder.append(newStr);
				}
				str = builder.toString();
			}
		} else {
			str = str.substring(0, 1).toUpperCase() + str.substring(1);
		}
		return str;
	}
	
}
